package com.xxx.blog.service.impl;

import com.github.pagehelper.PageHelper;
import com.xxx.blog.domain.ArticleType;
import com.xxx.blog.mapper.ArticleTypeMapper;
import com.xxx.blog.query.ArticleTypeQuery;
import com.xxx.blog.service.IArticleTypeService;
import com.xxx.blog.vo.ArticleTypeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @author BoWei Wang
 * @date 2025/8/5
 */
@Service
public class ArticleTypeServiceImpl implements IArticleTypeService {
    @Autowired
    private ArticleTypeMapper articleTypeMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<ArticleType> findAll() {
        return articleTypeMapper.findAll();
    }

    @Override
    public ArticleType findOne(Long id) {
        return articleTypeMapper.findOne(id);
    }

    @Override
    public List<ArticleType> queryPage(ArticleTypeQuery articleTypeQuery) {
        PageHelper.startPage(articleTypeQuery.getCurrentPage(), articleTypeQuery.getPageSize());
        return articleTypeMapper.queryPage(articleTypeQuery);
    }

    @Override
    @CacheEvict(cacheNames="type",key="'article'")
    public void addArticleType(ArticleType articleType) {
//        redisTemplate.delete("typeTree");
        articleTypeMapper.addArticleType(articleType);

//        try {
//            Thread.sleep(1000);
//        } catch (InterruptedException e) {
//            throw new RuntimeException(e);
//        }
//        redisTemplate.delete("typeTree");
    }

    @Override
//    @CacheEvict(cacheNames="type",key="'article'")
    @CachePut(cacheNames="type",key="'article'")
    public void updateArticleType(ArticleType articleType) {
        articleType.setUpdateTime(new Date());
        articleTypeMapper.updateArticleType(articleType);
    }

    @Override
    @CacheEvict(cacheNames="type",key="'article'")
    public void deleteArticleType(Long id) {
        articleTypeMapper.deleteArticleType(id);
    }

    @Override
    @CacheEvict(cacheNames="type",key="'article'")
    public void batchArticleTypes(Long[] ids) {
        articleTypeMapper.batchArticleTypes(ids);
    }

    @Override
    @Cacheable(cacheNames="type",key="'article'") //key=type::arcicle
    public List<ArticleType> getTypeTree(Long id) {

        List<ArticleType> typeTree = getArticleTypesTree(id);
        return typeTree;
        /*
         *
         * */
        //从redis中取
       /* Object typeTreeObj = redisTemplate.boundValueOps("typeTree").get();
        List<ArticleType> typeTree = null;
        if (typeTreeObj == null) {
            typeTree = getArticleTypesTree(id);
            redisTemplate.boundValueOps("typeTree").set(typeTree);
        }else {
                typeTree = (List<ArticleType>)typeTreeObj;
        }
        return typeTree;*/
    }


    private List<ArticleType> getArticleTypesTree(Long id) {
        // 定义返回的所有父类型集合
        List<ArticleType> typeTree = new ArrayList<>();
        // 所有类型
        List<ArticleType> all = articleTypeMapper.findAll();
        // 将所有类型放入map集合，方便通过子类型的parentId获取父类型
        // key为id，value为类型对象(行数据)
        Map<Long, ArticleType> typeMap = new HashMap<>();
        for (ArticleType articleType : all) {
            typeMap.put(articleType.getId(), articleType);
        }

        for (ArticleType articleType : all) {
            // 自己不能选择自己
            if (id.equals(articleType.getId())) {
                continue;
            }

            // 判断父类型id是否为空
            if (articleType.getParentId() == null) {
                // 父类型id为空则为父类型,将父类型放入父类型集合
                typeTree.add(articleType);
            } else {
                // 否则为子类型
                // 通过子类型的父类型id从map集合拿到父类型
                ArticleType parent = typeMap.get(articleType.getParentId());
                // 防空判断
                if (parent != null) {
                    // 拿到父类型添加子类型
                    parent.getChildren().add(articleType);
                }
            }
        }

        return typeTree;
    }

    @Override
    public List<ArticleTypeVo> getArticleTypeStatistics() {
        return articleTypeMapper.getArticleTypeStatistics();
    }
}
